#pragma once
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dcompiler.h>
#include <xnamath.h>
#include <D3DVoxelChunk.h>
#include <D3DVoxelTechniqueOne.h>

class D3DVoxelTechniqueTwo : public D3DVoxelTechniqueOne
{
public:

	// shader declarations

	// pass 1: visit each voxel and stream out a lightweight marker point for each
	// voxel that needs triangles. Use a stream-out query to skip remaining passes
	//  if no output here.
	ID3D11VertexShader*							m_pVSListNonempty;
	ID3D11GeometryShader*						m_pGSListNonempty;
	// buffers:
	// Input : voxel volume
	// output : UINT VoxelMarkers z8_y8_x8_case8; count 0 - 1 include extra row at the far end

	
	// pass 2: march the output from the previous pass and only generate vertices
	// at edges 3 0 8. stream out a marker point for each one that needs a vertex
	// on it.
	ID3D11VertexShader*							m_pVSGenVertices;
	ID3D11GeometryShader*						m_pGSGenVertices;
	// Input : (previous)
	// Output : UINT EdgeMarkers z8_y8_x8_null4_edge4; count 0 - 3
	ID3D11InputLayout*			                   m_pMarkerLayout;



	// pass 3: March the list and use the vertex shader to calculate the vertex positions
	// The GS just streams it out.
	ID3D11VertexShader*							m_pVSCalcVertices;
	ID3D11GeometryShader*						m_pGSCalcVertices;
	// Input : (previous)
	// Output : float4 position;  float3 normal; count 1

	


	// pass 4: march Marker308 and splat the vertex IDs.
	ID3D11VertexShader*								m_pVSSplat;
	ID3D11GeometryShader*						m_pGSSplat;
	ID3D11PixelShader*								m_pPSSplat;
	// Input : EdgeMarkers;
	// Output : VertexIDVolume UINT;
	ID3D11InputLayout*			                   m_pSplatInputLayout;

	// pass 5: 
	ID3D11VertexShader*								m_pVSGenIndices;
	ID3D11GeometryShader*						m_pGSGenIndices;

	ID3D11SamplerState*									m_pVertexIDVolumeSampler;
	// Input : VertexIDVolume, VoxelMarkers
	// Output : VoxelIndexBuffer;


public:
	D3DVoxelTechniqueTwo(ID3D11Device *, ID3D11DeviceContext *);
	// initializes vertex, geometry, pixel shaders
	void Release(void);

	virtual HRESULT InitMCShaders(void);
	HRESULT InitMCStage3Shaders(void);
	HRESULT InitMCStage3_2Shaders(void);
	HRESULT InitMCStage3_3Shaders(void);
	HRESULT InitMCStage3_4Shaders(void);
	HRESULT InitMCStage3_5Shaders(void);
	HRESULT ComputeIsosurface(D3DVoxelChunk * );

	HRESULT ComputeVoxelMarkers(D3DVoxelChunk * pChunk);
	HRESULT ComputeEdgeMarkers(D3DVoxelChunk * pChunk);
	HRESULT ComputeVertices(D3DVoxelChunk * pChunk);
	HRESULT ComputeVertexIDVolume(D3DVoxelChunk * pChunk);
	void ComputeIndices(D3DVoxelChunk * pChunk);

	void SetRenderTarget(D3DVoxelChunk * pChunk);

};
